package com.boyou.sytzc.core.service

import com.boyou.sytzc.utils.common.toDateString
import com.boyou.sytzc.core.appctx.AppApplication.Companion.deviceNoManager
import com.boyou.sytzc.core.receiver.BackgroundUploadReceiver
import android.annotation.SuppressLint
import android.app.Service
import java.lang.Thread
import android.content.Context
import com.yuge.yugecse.util.device.DeviceUtil
import android.net.ConnectivityManager
import com.boyou.sytzc.utils.database.RecordDbHelper
import com.boyou.sytzc.data.entity.RecordInfoEntity
import java.util.LinkedHashMap
import com.boyou.sytzc.api.ApiService
import org.simple.eventbus.EventBus
import com.boyou.sytzc.data.event.DataChangedEvent
import java.lang.Exception
import android.text.TextUtils
import java.io.File
import java.util.Objects
import com.google.gson.GsonBuilder
import android.content.Intent
import android.content.IntentFilter
import com.boyou.sytzc.data.event.UploadNotifyEvent
import android.os.IBinder
import com.boyou.sytzc.api.HttpApiManager
import com.boyou.sytzc.utils.app.AppConfig
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.simple.eventbus.Subscriber

/**
 * Created by Cosecant on 2015/9/19.
 * 后台上传数据服务
 */
class UploadService : Service() {

    companion object {
        @JvmField
        var isUploading = false //是否正在上传
    }

    private val appConfig by lazy { AppConfig.singleton() }

    private var uploadReceiver: BackgroundUploadReceiver? = null

    /** 上传记录信息 **/
    @SuppressLint("SimpleDateFormat")
    private fun uploadRecordInfoNow() = Thread {
        synchronized(this@UploadService) { //同步代码
            startUpload(this@UploadService)
        }
    }.start()

    private fun startUpload(context: Context) {
        val isNetAvailable = DeviceUtil.isNetAvailable(context)
        val netType = DeviceUtil.getAvailableNetworkType(context)
        val isWifiUpload = appConfig.isWifiUpload
        if (isWifiUpload && netType != ConnectivityManager.TYPE_WIFI) return  //如果开启了wifi上传，但是网络不是wifi,禁止上传
        while (isNetAvailable &&  /*BackgroundUploadService.isUpload &&*/!isUploading) {
            isUploading = true //标识为正在上传
            try {
                val recordDbHelper = RecordDbHelper.getInstance(context)
                val recordInfo = recordDbHelper.noUploadRecordInfo
                if (recordInfo != null) { //如果数据存在，则上传
                    try {
                        val domainUrl =
                            String.format("%s/api.php?h=device/carrecord", appConfig.serverUrl)
                        val paramMaps = buildUploadDataParams(recordInfo)
                        val result = HttpApiManager.getApiService(context, ApiService::class.java)
                            .uploadRecord(domainUrl, paramMaps).execute()
                        if (result.isSuccessful) {
                            try {
                                val responseBody = result.body()
                                if (responseBody != null && responseBody.state) {
                                    recordInfo.isUpload = 1 //设为已上传状态
                                    recordInfo.uploadInfo = "数据已成功上传"
                                    recordDbHelper.changeRecordState(recordInfo) //修改记录上传状态
                                } else {
                                    recordInfo.uploadInfo =
                                        if (responseBody != null) getResourceString(responseBody.code) else "发生未知错误"
                                    recordDbHelper.changeRecordUploadInfo(recordInfo)
                                }
                                isUploading = false //标识为不上传
                                EventBus.getDefault().post(DataChangedEvent())
                                Thread.sleep(3000)
                                continue  //暂停3秒继续上传
                            } catch (e: Exception) {
                                e.printStackTrace()
                                recordInfo.uploadInfo = "解析数据异常，等待上传"
                                recordDbHelper.changeRecordUploadInfo(recordInfo)
                            }
                            isUploading = false //标识为不上传
                            EventBus.getDefault().post(DataChangedEvent())
                            continue
                        } else {
                            recordInfo.uploadInfo = "网络发生异常，等待上传"
                            recordDbHelper.changeRecordUploadInfo(recordInfo)
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                        recordInfo.uploadInfo = "网络发生异常，等待上传"
                        recordDbHelper.changeRecordUploadInfo(recordInfo)
                    }
                }
                isUploading = false //标识为不上传
                EventBus.getDefault().post(DataChangedEvent())
                Thread.sleep(3000)
                continue  //继续循环操作
            } catch (e: Exception) {
                e.printStackTrace()
            }
            isUploading = false //标识为不上传
            EventBus.getDefault().post(DataChangedEvent())
        }
    }

    private fun buildUploadDataParams(recordInfo: RecordInfoEntity): LinkedHashMap<String, RequestBody> {
        val paramMaps = LinkedHashMap<String, RequestBody>()
        val deviceNo = when {
            TextUtils.isEmpty(recordInfo.deviceNo) -> Objects.requireNonNull(deviceNoManager.deviceNo)
            else -> Objects.requireNonNull(recordInfo.deviceNo)
        }
        if (!deviceNo.isNullOrEmpty()) paramMaps["no"] = deviceNo.toRequestBody()
        if (!recordInfo.picture.isNullOrEmpty()) {
            val imgFile = File(recordInfo.picture!!)
            if (imgFile.exists()) { //如果存在图片才加入该参数
                val key =
                    "img\"; filename=\"" + recordInfo.time.toDateString("yyyyMMddHHmmss") + ".jpg"
                paramMaps[key] = imgFile.asRequestBody("application/octet-stream".toMediaType())
            }
        }
        if (recordInfo.sjNo != null)
            paramMaps["sjno"] = recordInfo.sjNo!!.toRequestBody()
        paramMaps["posi"] = recordInfo.posi.toString().toRequestBody()
        if (recordInfo.carNo != null)
            paramMaps["car"] = recordInfo.carNo!!.toRequestBody()
        if (recordInfo.lineNo != null)
            paramMaps["line"] = recordInfo.lineNo!!.toRequestBody()
        paramMaps["ctime"] = recordInfo.time.toDateString("yyyy-MM-dd HH:mm:ss").toRequestBody()
        paramMaps["coord_x"] = recordInfo.locx.toString().toRequestBody()
        paramMaps["coord_y"] = recordInfo.locy.toString().toRequestBody()
        paramMaps["packet"] = GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
            .create().toJson(recordInfo.packet)
            .toRequestBody()
        return paramMaps
    }

    private fun getResourceString(code: Int): String =
        getString(resources.getIdentifier("uploadRecordErr_$code", "string", packageName))

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        if (uploadReceiver == null) {
            uploadReceiver = BackgroundUploadReceiver()
            val filter = IntentFilter()
            filter.addAction(Intent.ACTION_SCREEN_ON)
            filter.addAction(Intent.ACTION_SCREEN_OFF)
            this.registerReceiver(uploadReceiver, filter)
        }
        return START_STICKY
    }

    override fun onCreate() {
        super.onCreate()
        EventBus.getDefault().register(this)
        uploadRecordInfoNow() //上传数据操作
    }

    @Subscriber
    fun onUploadStateChangeEvent(event: UploadNotifyEvent?) {
        uploadRecordInfoNow() //上传记录信息
    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        if (uploadReceiver != null) unregisterReceiver(uploadReceiver)
    }

    override fun onBind(intent: Intent): IBinder? = null

}